package com.tqjc.system.core.pipeline.util;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tqjc.business.interactivewithscan.consts.DeviceEnum;
import com.tqjc.business.interactivewithscan.core.data.AskData.AskData;
import com.tqjc.business.interactivewithscan.core.data.PointData.PointData;
import com.tqjc.business.interactivewithscan.core.thread.crane.CraneScanThread;
import com.tqjc.business.interactivewithscan.core.thread.grab.SteelGrabPointThread;
import com.tqjc.business.interactivewithscan.core.thread.tanker.DoubleTankerScanThread;
import com.tqjc.business.interactivewithscan.core.thread.tanker.SingleTankerScanThread;
import com.tqjc.business.interactivewithscan.entity.Coord;
import com.tqjc.business.interactivewithscan.entity.LiftingPoint;
import com.tqjc.system.common.constant.AddTaskConstant;
import com.tqjc.system.common.constant.GlobalConstant;
import com.tqjc.system.common.constant.RemoteURLConstant;
import com.tqjc.system.common.entity.BO.*;
import com.tqjc.system.common.enums.CarEnum;
import com.tqjc.system.common.enums.CarPLCInfoEnum;
import com.tqjc.system.common.enums.TankCarNoEnum;
import com.tqjc.system.common.exception.AddTaskException;
import com.tqjc.system.core.redis.RedisApi;
import com.tqjc.system.core.scan.thread.AsynTankCarScanThread;
import com.tqjc.system.core.threadpool.ThreadPoolManager;
import com.tqjc.system.core.util.DateUtils;
import com.tqjc.system.core.util.HttpsUtils;
import com.tqjc.system.core.util.PLCHttpsUtils;
import com.tqjc.system.core.util.SpringUtils;
import com.tqjc.system.system.entity.SysAreaInfoEntity;
import com.tqjc.system.system.service.SysAreaInfoService;
import com.tqjc.system.system.util.SystemUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 86195
 * @version 1.0
 * @description TODO
 * @date 2023/12/3 12:44
 */
@Slf4j
public class ScanUtils {


    public static final String SCAN_TANK_CAR_A = "A";

    public static final String SCAN_TANK_CAR_B = "B";

    /**
     * 双轨槽车位置  1号车是左边   2号车是右边   3号车统一用左边   天车大车坐标较小的那一侧是右
     */
    public static final String SCAN_DIRECTION_LEFT = "1";


    public static final String SCAN_DIRECTION_RIGHT = "2";


    public static final String SCAN_STEEL_SPAN = "M";

    public static final String SCAN_DREGS_SPAN = "N";


    public static final String SCAN_TANK_CAR_LOCK = "scan_tank_car_lock";



    /**
     * 双轨槽车扫描
     */
    public static final int SCANNER_TANK_CAR_DOUBEL = 2;


    /**
     * 宽轨槽车扫描
     */
    public static final int SCANNER_TANK_CAR_WIDE = 1;

    /**
     * 1号槽车扫描完成标识
     */
    public static boolean TANK_CAR_1_SCAN_FLAG ;

    /**
     * 2号槽车扫描完成标识
     */
    public static boolean TANK_CAR_2_SCAN_FLAG ;

    /**
     * 3号槽扫描完成标识
     */
    public static boolean TANK_CAR_3_SCAN_FLAG ;


    /**
     * 1号槽车抓点信息
     */
    public static TankCarPointBO TANK_CAR_NO1_POINT_INFO ;


    /**
     * 2号槽车抓点信息
     */
    public static TankCarPointBO TANK_CAR_NO2_POINT_INFO ;



    /**
     * 3号槽车抓点信息
     */
    public static TankCarPointBO TANK_CAR_NO3_POINT_INFO ;


    /**
     * 3号槽车计数
     */
    public static int TANK_CAR_NO3_POINT_COUNT ;


    /**
     * 2号槽车计数
     */
    public static int TANK_CAR_NO2_POINT_COUNT ;


    /**
     * 1号槽车计数
     */
    public static int TANK_CAR_NO1_POINT_COUNT ;


    /**
     * 1号槽车返回的总数
     */
    public static int TANK_CAR_NO1_POINT_SIZE ;



    /**
     * 2号槽车返回的总数
     */
    public static int TANK_CAR_NO2_POINT_SIZE ;


    /**
     * 3号槽车返回的总数
     */
    public static int TANK_CAR_NO3_POINT_SIZE ;


    /**
     * 上一次槽车扫描时间
     */
    public static long LAST_TANK_CAR_SCAN_TIME;


    public static final Map<String,TankCarNoEnum> tankCarScanFlagMap = new HashMap(3){{
        put(TankCarNoEnum.NO_1.getTankName(),TankCarNoEnum.NO_1);
        put(TankCarNoEnum.NO_2.getTankName(),TankCarNoEnum.NO_2);
        put(TankCarNoEnum.NO_3.getTankName(),TankCarNoEnum.NO_3);
    }};




    /**
     * 废渣跨库区抓点
     */
//    private static CraneScanThread slagGrabPointThread = SpringUtils.getBean("CraneScanThread");

    /**
     * 废钢跨库区抓点
     */
//    private static SteelGrabPointThread steelGrabPointThread = SpringUtils.getBean("SteelGrabPointThread");


    /**
     * 废钢跨库区抓点
     */
//    private static CraneScanThread craneScanThread = SpringUtils.getBean("CraneScanThread");

    private static RedisApi redisService = SpringUtils.getBean(RedisApi.class);


//    /**
//     * 双轨槽车  第一个轨道槽车
//     */
//    private static FirstDoubleTrackTankScanThread firstDoubTankThread = SpringUtils.getBean("FirstDoubleTrackTankScanThread");
//
//
//    /**
//     *双规槽车   第一个轨道槽车
//     */
//    private static SecondDoubleTrackTankScanThread secondDoubTankThread = SpringUtils.getBean("SecondDoubleTrackTankScanThread");
//
//
//    /**
//     * 单轨槽车   第一个槽车
//     */
//    private static FirstSingleTrackTankScanThread firstSingTankThread = SpringUtils.getBean("FirstSingleTrackTankScanThread");
//
//    /**
//     * 单轨槽车   第二个槽车
//     */
//    private static SecondSingleTrackTankScanThread secondSingTankThread = SpringUtils.getBean("SecondSingleTrackTankScanThread");


//    private static DoubleTankerScanThread doubleTankerScanThread = SpringUtils.getBean("DoubleTankerScanThread");
//
//    private static SingleTankerScanThread singleTankerScanThread = SpringUtils.getBean("SingleTankerScanThread");



    private static SysAreaInfoService service = SpringUtils.getBean("SysAreaInfoService");


//    public static void scanTankCar(AskData askData){
//        singleTankerScanThread.addAskDataQue(askData);
//
//    }






//    public static Coord getTankCarPoint(String tankCarNo,int scanType) throws AddTaskException {
//        String askId = UUID.randomUUID().toString();
//        AskData askData = new AskData();
//        askData.setAskId(askId);
//        askData.setScanType(scanType);
//
//        if(TankCarNoEnum.NO_3.getTankCarNo().equals(tankCarNo)){
//            //3号槽车宽轨
//            askData.setType(DeviceEnum.Tanker_Wide_Track_3.getDeviceCode());
//            singleTankerScanThread.addAskDataQue(askData);
//            while (true){
//                try {
//                    Thread.sleep(3*1000);
//                    //TODO:
//                    PointData pointData = singleTankerScanThread.responseMap.get(askId);
//                    if(pointData != null){
//                    singleTankerScanThread.responseMap.remove(askId);
//                        return pointData.getPointData().get(0);
//                    }
//                    return null;
//                } catch (Exception e) {
//                    log.error("宽轨槽车获取放点异常",e);
//                    throw new AddTaskException("宽轨槽车获取放点异常");
//                }
//            }
//
//        } else {
//            askData.setType(TankCarNoEnum.NO_1.getTankCarNo().equals(tankCarNo) ? DeviceEnum.Tanker_Double_Track_1.getDeviceCode() :DeviceEnum.Tanker_Double_Track_2.getDeviceCode());
//            doubleTankerScanThread.addAskDataQue(askData);
//            while (true){
//                try {
//                    Thread.sleep(2*1000);
//                    PointData pointData = doubleTankerScanThread.responseMap.get(askId);
//                    if(pointData != null){
//                        doubleTankerScanThread.responseMap.remove(askId);
//                        return pointData.getPointData().get(0);
//                    }
//                } catch (Exception e) {
//                    log.error("双轨槽车获取放点异常",e);
//                    throw new AddTaskException("双轨槽车获取放点异常");
//                }
//            }
//        }
//
//    }


    /**
     * 获取库区抓点位置
     * @return
     */
//    public static synchronized Coord getSpanGrabPoint(String spanNo,String carNo,String materialNo,int areaNum) throws InterruptedException {
////        SysAreaInfoEntity sysAreaInfoEntity = service.queryMaterialNoIndex(materialNo, spanNo, areaNum);
////        int rightBottomY = sysAreaInfoEntity.getIndexRightBottomY();
////        int leftTopX = sysAreaInfoEntity.getIndexLeftTopX();
////        int rightBottomX = sysAreaInfoEntity.getIndexRightBottomX();
////        int leftTopY = sysAreaInfoEntity.getIndexLeftTopY();
//        if(AddTaskConstant.WASTE_STEEL_SPAN_NO.equals(spanNo)){
//            //渣跨
//
//            String askId = UUID.randomUUID().toString();
//            AskData askData = new AskData();
//            askData.setAskId(askId);
//            askData.setScanType(1);
//            askData.setAreaId(String.valueOf(areaNum));
//            log.info("废渣跨天车：{}开始获取抓点,askId:{}。。。。",carNo,askId);
//            try {
//
//                craneScanThread.addAskDataQue(askData);
//                while (true){
//                    try {
//                        Thread.sleep(2000);
//                        log.info("废钢跨天车：{},准备获取抓点,askId:{}。。。。",carNo,askId);
//                        PointData pointData = craneScanThread.responseMap.get(askId);
//                        if(pointData != null && pointData.getPointData().size() != 0){
//                            craneScanThread.responseMap.remove(askId);
//                            Random ran = new Random();
//                            int size = pointData.getPointData().size();
//                            int ranNum = ran.nextInt(size - 1);
//                            log.info("废钢跨天车：{}，获取抓点结束,askId:{}。。。。",carNo,askId);
//                            log.info("废钢跨天车：{}，获取扫描抓点为：{}",carNo,pointData);
//                            Coord coord = pointData.getPointData().get(ranNum);
//                            log.info("废钢跨天车：{}，随机数为：{}，获取抓点为：{}",carNo,ranNum,coord);
//                            return coord;
//                        }
//                        log.info("废钢跨天车：{},未获取抓点结束,askId:{}，循环。。。。",carNo,askId);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                }
//
//            } catch (Exception e){
//
//            }
//
//
////            //废钢跨
////            String deviceCode = CarEnum.CAR_NO_1.getCarNo().equals(carNo) ? DeviceEnum.Tianche_Steel_1.getDeviceCode() : DeviceEnum.Tianche_Steel_2.getDeviceCode();
////            Map<String, LiftingPoint> points = null;
////            while (points == null || points.size() == 0){
////                try {
////                    points = steelGrabPointThread.getPoints(deviceCode);
////                    Thread.sleep(3*1000);
////                    log.info("废钢跨获取抓点。。。。");
////
////                } catch (Exception e){
////                    throw e;
////
////                }
////            }
////
////            for (Map.Entry<String, LiftingPoint> entry : points.entrySet()) {
////                LiftingPoint value = entry.getValue();
////                List<Coord> point = value.getPoint();
////                for (Coord coord : point) {
////                    if(coord.getX() <= leftTopX && coord.getX() >= rightBottomX  ){
////                        return coord;
////                    }
////                }
////            }
//
//
//
//        }
//
//
//        if(AddTaskConstant.DREGS_STEEL_SPAN_NO.equals(spanNo)){
//            //渣跨
//
//            String askId = UUID.randomUUID().toString();
//            AskData askData = new AskData();
//            askData.setAskId(askId);
//            askData.setScanType(2);
//            askData.setAreaId(String.valueOf(areaNum));
//            log.info("废渣跨天车：{}开始获取抓点,askId:{}。。。。",carNo,askId);
//
//            slagGrabPointThread.addAskDataQue(askData);
//            while (true){
//                try {
//                    Thread.sleep(2000);
//                    log.info("废渣跨天车：{}准备获取抓点,askId:{}。。。。",carNo,askId);
//                    PointData pointData = slagGrabPointThread.responseMap.get(askId);
//                    if(pointData != null && pointData.getPointData().size() != 0){
//                        slagGrabPointThread.responseMap.remove(askId);
//                        Random ran = new Random();
//                        int size = pointData.getPointData().size();
//                        int ranNum = ran.nextInt(size - 1);
//                        log.info("废渣跨天车：{}，获取抓点结束,askId:{}。。。。",carNo,askId);
//                        log.info("废渣跨天车：{}，获取扫描抓点为：{}",carNo,pointData);
//                        Coord coord = pointData.getPointData().get(ranNum);
//                        log.info("废渣跨天车：{}，随机数为：{}，获取抓点为：{}",carNo,ranNum,coord);
//                        return coord;
//                    }
//                    log.info("废渣跨天车：{}未获取抓点结束,askId:{}，循环。。。。",carNo,askId);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//
//        return null;
//    }

    public static Coord getTestTankCarPoint(String workingSpanNo,TankCarNoEnum tankCarNoEnum,String test) {
        //1.得到当前槽车的位置
        String tankName = tankCarNoEnum.getTankName();
        Map<String,String> tankParamMap = new HashMap<>(2);
        tankParamMap.put(GlobalConstant.STRING_SN,GlobalConstant.TANK_CAR_SN_VAL);
        tankParamMap.put(GlobalConstant.STRING_LABEL,tankName + "实际位置");
        Coord coord = new Coord();

        try {
            ResponseLabelDataBO responseLabelDataBO = HttpsUtils.sendPost(RemoteURLConstant.URL_READBC, JSON.toJSONString(tankParamMap), ResponseLabelDataBO.class);
            Map<String, String> content = responseLabelDataBO.getContent();
            int tankCarIndex = content != null ? Integer.valueOf(content.get("currentVal").toLowerCase()): 0;

            //Z点写死
            coord.setZ(10624);
            //

            if(AddTaskConstant.WASTE_STEEL_SPAN_NO.equals(workingSpanNo)){
                //废钢
                coord.setY(tankCarIndex + 20000);

                if("1".equals(tankCarNoEnum.getTankCarNo())){
                    coord.setX(95400);
                }

                if("2".equals(tankCarNoEnum.getTankCarNo())){
                    coord.setX(91482);
                }

                if("3".equals(tankCarNoEnum.getTankCarNo())){
                    //右边（大值边）
                    coord.setX(111110);

                }
                //废钢跨   大车位置采点
                //小车位置需要计算


            } else {
                //渣钢跨
                coord.setY(38000 -  tankCarIndex);
//                if("1".equals(tankCarNoEnum.getTankCarNo())){
//
//                    coord.setY(11166);
//                }

                if("1".equals(tankCarNoEnum.getTankCarNo())){
                    coord.setX(95719);

                }

                if("2".equals(tankCarNoEnum.getTankCarNo())){
                    coord.setX(91435);

                }

                if("3".equals(tankCarNoEnum.getTankCarNo())){
                    //右边（大值）
                    coord.setX(111110);

//                    if("1".equals(test)){
//                        coord.setX(111110);
//
//                    }
//                    if("2".equals(test)){
//                        coord.setX(111110);
//
//                    }

                }




            }

        } catch (Exception e){
            log.error("测试异常",e);

        }

        return coord;
    }

    /**
     * 启动扫描并且翻转槽车扫描状态
     * @param tankCarNoEnum
     * @param spanNo
     * @throws AddTaskException
     */
    public static void startAndReceiveRes(TankCarNoEnum tankCarNoEnum,String spanNo) throws AddTaskException {
        try {
            synchronized (ScanUtils.SCAN_TANK_CAR_LOCK){
                TankCarNoEnum flag = tankCarScanFlagMap.get(tankCarNoEnum.getTankName());
                if(flag == null){
                    log.info("槽车编号:{}扫描已启动，无需重复启动!!!",tankCarNoEnum.getTankName());
                    return;
                }
                //移除
                tankCarScanFlagMap.remove(tankCarNoEnum.getTankName());
            }

            //1.启动扫描,翻转对应槽车扫描仪的状态
            long currentTimeMillis = System.currentTimeMillis();
            while (true){
                //保证与上一次槽车扫描间隔30s
                if(LAST_TANK_CAR_SCAN_TIME == 0 || currentTimeMillis - LAST_TANK_CAR_SCAN_TIME > 30 * 1000){

                    break;
                }
                log.info("启动槽车扫描，与上一次间隔未超过30s。等待中。。。。。。");
                Thread.sleep(1*1000);
            }

            updateTankCarFlag(tankCarNoEnum,false);
            LAST_TANK_CAR_SCAN_TIME = currentTimeMillis;
            boolean startFlag = startTankCarScan(tankCarNoEnum, spanNo);
            if(!startFlag){
                //返回false，启动未成功
                throw new AddTaskException("请求启动槽车扫描不成功");
            }
            //2.判断该位置的扫描是否已完成，并且改变状态值
            Thread.sleep(30*1000);
            TankCarPointBO tankCarPoint = callTankCarPoint(tankCarNoEnum, spanNo);

            int i = 1;
            while (tankCarPoint == null || CollectionUtil.isEmpty(tankCarPoint.getDropPos())){
                log.info("槽车：{}扫描循环中。。。。",tankCarNoEnum.getTankName());
                if(tankCarPoint != null && StringUtils.isNotEmpty(tankCarPoint.getError())){

                    log.warn("槽车：{}扫描出现异常，异常信息为：{}",tankCarNoEnum.getTankName(),tankCarPoint.getError());
                }
                startFlag = startTankCarScan(tankCarNoEnum, spanNo);
                //等待30秒，让扫描完成
                Thread.sleep(30*1000);
                tankCarPoint = callTankCarPoint(tankCarNoEnum, spanNo);

                if(tankCarPoint != null && StringUtils.isNotEmpty(tankCarPoint.getError())){

                    log.warn("槽车：{}扫描出现异常，异常信息为：{}",tankCarNoEnum.getTankName(),tankCarPoint.getError());
                }


                log.info("获取的槽点数据为：{}",tankCarPoint);
                i++;
                if(i > 2){
                    throw new AddTaskException("槽车扫描异常！！！");
                }
//                if(i > 1){
//                    //重发请求三次后，发起重连请求   sendGet
//                    log.info("槽车：{}扫描出现异常三次，发起重连请求",tankCarNoEnum.getTankName());
//
//                    HttpsUtils.sendPost(RemoteURLConstant.URL_TANK_CAR_SCAN_RECONNECT);
//                    //等待30秒，让初始化完成
//                    Thread.sleep(30*1000);
//                    startFlag = startTankCarScan(tankCarNoEnum, spanNo);
//                    //等待30秒，让扫描完成
//                    Thread.sleep(30*1000);
//                    tankCarPoint = callTankCarPoint(tankCarNoEnum, spanNo);
//                    i = 1;
//                }
            }
            //过滤槽车扫描点
            tankCarPoint.setResPos(filterTankCarPoint(spanNo,tankCarPoint));
            //扫描完成
            setTankCarSize(tankCarNoEnum,tankCarPoint.getDropPos().size());
            setTankCarCount(tankCarNoEnum,0);
            setTankCarPointInfo(tankCarNoEnum,tankCarPoint);
            updateTankCarFlag(tankCarNoEnum,true);
            log.info("槽车：{}完成扫描",tankCarNoEnum.getTankName());

        } catch (Exception e){
            log.info("槽车扫描startAndReceiveRes方法运行异常",e);

        } finally {
            tankCarScanFlagMap.put(tankCarNoEnum.getTankName(),tankCarNoEnum);

        }


    }

    /**
     * 供行车加料   获取槽车点位方法
     * @param tankCarNoEnum
     * @param spanNo
     * @return
     */
    public static synchronized Coord getTankCarPoint(TankCarNoEnum tankCarNoEnum,String spanNo){
        if(AddTaskConstant.TANKCAR_SCAN_USE_FLAG){
            //启用槽车扫描
            // tankCarFlag  true:扫描完成
            boolean tankCarFlag = getTankCarFlag(tankCarNoEnum);
            TankCarPointBO tankCarPointBO = null;

            try {
                long startTime = System.currentTimeMillis();
                while (!tankCarFlag){
                    log.info("检查槽车扫描是否完成。。。。");
                    //扫描没有完成
                    Thread.sleep(3*1000);
                    tankCarFlag = getTankCarFlag(tankCarNoEnum);
                    long endTime = System.currentTimeMillis();
                    if(endTime - startTime > 13 * 60 *1000){
                        log.error("槽车扫描长时间没有点数据");
                        return null;
                    }
                }
                tankCarPointBO = getTankCarPointBO(tankCarNoEnum);
            } catch (Exception e){
                log.error("获取槽车扫描点异常",e);
            }
            //获取当前的下标值
            int tankCarCount = getTankCarCount(tankCarNoEnum);
            //获取本次槽车扫描的总个数
            int tankCarSize = getTankCarSize(tankCarNoEnum);
            log.info("槽车名称:{}获取抓点。当前tankCarCount次数为：{},tankCarSize集合长度为：{}",tankCarNoEnum.getTankName(),tankCarCount,tankCarSize);
            int index = tankCarCount % tankCarSize;
            DropPosition dropPosition = tankCarPointBO.getResPos().get(index);
            log.info("槽车名称:{}获取抓点。当前抓点下标为：{},获取的槽车放点数据为：{}",tankCarNoEnum.getTankName(),index,dropPosition);
            tankCarCount++;
            //更新下标值
            setTankCarCount(tankCarNoEnum,tankCarCount);

            if(tankCarCount + 1 >= AddTaskConstant.SCAN_VALID_COUNT  ){
                //启动异步线程处理  重新启动扫描  已经满足两次扫描了
                log.info("已用过一遍槽车点位，启动异步槽车扫描线程");
                ThreadPoolManager.getInstance().execute(AsynTankCarScanThread.builder().tankCarNoEnum(tankCarNoEnum).spanNo(spanNo).build());
            }

            return dropPosition.toCoord();

        }

        Coord coord = getTestTankCarPoint(spanNo, tankCarNoEnum, null);

        //转换成dropPosition对象
        return coord;

    }






    /**
     * 槽车扫描启动
     * @param tankCarNoEnum  槽车枚举
     * @param spanNo   跨区号
     * @return
     */
    private static boolean startTankCarScan(TankCarNoEnum tankCarNoEnum,String spanNo) throws IOException, URISyntaxException {
        String scanParam = getTankCarReqID(tankCarNoEnum, spanNo);
        log.info("槽车：{}启动扫描，库区参数是：{},ReqID是：{}",tankCarNoEnum.getTankName(),spanNo,scanParam);
        Map map = new HashMap(1);
        map.put("reqID",scanParam);
        String s = JSONObject.toJSONString(map);
        return HttpsUtils.sendParamsPost(RemoteURLConstant.URL_TANK_CAR_SCAN_START ,"reqID",scanParam ,Boolean.class);
    }

    private static String getTankCarReqID(TankCarNoEnum tankCarNoEnum, String spanNo) {
        //方向
        String scanDirection;
        String scanTankNo;
        String scanSpanNo;
        if(tankCarNoEnum == TankCarNoEnum.NO_3){
            //宽轨槽车
            scanTankNo = ScanUtils.SCAN_TANK_CAR_A;
            scanDirection = ScanUtils.SCAN_DIRECTION_LEFT;
        } else if(tankCarNoEnum == TankCarNoEnum.NO_1){
            //双轨槽车
            scanTankNo = ScanUtils.SCAN_TANK_CAR_B;
            //左边
            scanDirection = ScanUtils.SCAN_DIRECTION_LEFT;
        } else {
            //双轨槽车
            scanTankNo = ScanUtils.SCAN_TANK_CAR_B;
            //右边
            scanDirection = ScanUtils.SCAN_DIRECTION_RIGHT;
        }
        //扫描跨区
        scanSpanNo = AddTaskConstant.WASTE_STEEL_SPAN_NO.equals(spanNo) ? ScanUtils.SCAN_STEEL_SPAN : ScanUtils.SCAN_DREGS_SPAN;

        StringBuilder sb = new StringBuilder();
        String timeStr = DateUtils.getDate2StrYYYYMMDDHHMMSS();
        String scanParam = sb.append(scanTankNo).append(scanDirection).append(scanSpanNo).append(timeStr).toString();
        return scanParam;
    }


    public static TankScanStatusResBO getScannerStatus(int scannerNo){
        Map map = new HashMap(1);
        map.put("scanner",scannerNo);
        return PLCHttpsUtils.sendGet(RemoteURLConstant.URL_TANK_CAR_SCAN_STATUS, map, TankScanStatusResBO.class);


    }

    /**
     * 系统与槽车扫描交互
     * @param tankCarNoEnum
     * @param spanNo
     * @return
     */
    private static TankCarPointBO callTankCarPoint(TankCarNoEnum tankCarNoEnum,String spanNo) throws AddTaskException {
        String reqID = ScanUtils.getTankCarReqID(tankCarNoEnum, spanNo);
        log.info("发送获取槽车放点请求，reqID为：{}",reqID);
        Map map = new HashMap(1);
        map.put("reqID",reqID);
        return PLCHttpsUtils.sendGet(RemoteURLConstant.URL_TANK_CAR_SCAN_POINT, map, TankCarPointBO.class);

    }


    public static void updateTankCarFlag(TankCarNoEnum tankCarNoEnum,boolean value){
        if(tankCarNoEnum == TankCarNoEnum.NO_1){
            ScanUtils.TANK_CAR_1_SCAN_FLAG = value;
        }
        if(tankCarNoEnum == TankCarNoEnum.NO_2){
            ScanUtils.TANK_CAR_2_SCAN_FLAG = value;
        }

        if(tankCarNoEnum == TankCarNoEnum.NO_3){
            ScanUtils.TANK_CAR_3_SCAN_FLAG = value;
        }

    }


    public static boolean getTankCarFlag(TankCarNoEnum tankCarNoEnum){
        if(tankCarNoEnum == TankCarNoEnum.NO_1){
            return ScanUtils.TANK_CAR_1_SCAN_FLAG;
        }
        if(tankCarNoEnum == TankCarNoEnum.NO_2){
            return ScanUtils.TANK_CAR_2_SCAN_FLAG;
        }

        return ScanUtils.TANK_CAR_3_SCAN_FLAG;

    }


    public static void setTankCarPointInfo(TankCarNoEnum tankCarNoEnum,TankCarPointBO tankCarPointBO){
        if(tankCarNoEnum == TankCarNoEnum.NO_1){
            ScanUtils.TANK_CAR_NO1_POINT_INFO = tankCarPointBO;
        }
        if(tankCarNoEnum == TankCarNoEnum.NO_2){
            ScanUtils.TANK_CAR_NO2_POINT_INFO = tankCarPointBO;
        }
        if(tankCarNoEnum == TankCarNoEnum.NO_3){
            ScanUtils.TANK_CAR_NO3_POINT_INFO = tankCarPointBO;
        }


    }



    public static TankCarPointBO getTankCarPointBO(TankCarNoEnum tankCarNoEnum){
        if(tankCarNoEnum == TankCarNoEnum.NO_1){
            return ScanUtils.TANK_CAR_NO1_POINT_INFO;
        }
        if(tankCarNoEnum == TankCarNoEnum.NO_2){
            return ScanUtils.TANK_CAR_NO2_POINT_INFO;
        }

        return ScanUtils.TANK_CAR_NO3_POINT_INFO;

    }


    public static int getTankCarCount(TankCarNoEnum tankCarNoEnum){
        if(tankCarNoEnum == TankCarNoEnum.NO_1){
            return ScanUtils.TANK_CAR_NO1_POINT_COUNT;
        }
        if(tankCarNoEnum == TankCarNoEnum.NO_2){
            return ScanUtils.TANK_CAR_NO2_POINT_COUNT;
        }

        return ScanUtils.TANK_CAR_NO3_POINT_COUNT;

    }



    public static void setTankCarCount(TankCarNoEnum tankCarNoEnum,int value){
        if(tankCarNoEnum == TankCarNoEnum.NO_1){
            ScanUtils.TANK_CAR_NO1_POINT_COUNT = value;
        }
        if(tankCarNoEnum == TankCarNoEnum.NO_2){
            ScanUtils.TANK_CAR_NO2_POINT_COUNT = value;
        }
        if(tankCarNoEnum == TankCarNoEnum.NO_3){
            ScanUtils.TANK_CAR_NO3_POINT_COUNT = value;
        }


    }


    public static int getTankCarSize(TankCarNoEnum tankCarNoEnum){
        if(tankCarNoEnum == TankCarNoEnum.NO_1){
            return ScanUtils.TANK_CAR_NO1_POINT_SIZE;
        }
        if(tankCarNoEnum == TankCarNoEnum.NO_2){
            return ScanUtils.TANK_CAR_NO2_POINT_SIZE;
        }

        return ScanUtils.TANK_CAR_NO3_POINT_SIZE;

    }



    public static void setTankCarSize(TankCarNoEnum tankCarNoEnum,int value){
        if(tankCarNoEnum == TankCarNoEnum.NO_1){
            ScanUtils.TANK_CAR_NO1_POINT_SIZE = value;
        }
        if(tankCarNoEnum == TankCarNoEnum.NO_2){
            ScanUtils.TANK_CAR_NO2_POINT_SIZE = value;
        }

        if(tankCarNoEnum == TankCarNoEnum.NO_3){
            ScanUtils.TANK_CAR_NO3_POINT_SIZE = value;
        }

    }

    /**
     *
     * @param spanNo  库区类型
     * @param materialNo  材料编码
     * @param type  扫描点的类型   0：吸点   1：放点
     * @return
     */
    public synchronized static Coord  getAreaPointBO(String spanNo,String materialNo,int type){
        int count = 0;
        SysAreaInfoEntity sysAreaInfoEntity = service.queryMaterialNoIndex(materialNo, spanNo);
        int leftTopX = sysAreaInfoEntity.getIndexLeftTopX();
        int rightBottomX = sysAreaInfoEntity.getIndexRightBottomX();
        int indexRightBottomY = sysAreaInfoEntity.getIndexRightBottomY();
        int indexLeftTopY = sysAreaInfoEntity.getIndexLeftTopY();
        leftTopX = leftTopX - 620;
        rightBottomX = rightBottomX + 620;
        String tag;
        if(AddTaskConstant.WASTE_STEEL_SPAN_NO.equals(spanNo)){
            //废钢跨
            tag = leftTopX <= 204000 && rightBottomX > 114000 ? "A1" : "A2";
        } else {
            //废渣跨
            tag = leftTopX <= 204000 && rightBottomX > 114000 ? "B1" : "B2";
        }
        StringBuilder sb = new StringBuilder(GlobalConstant.MATERIAL_AREA_PARAM_REDIS_PREFIX);
        sb.append(tag);
        String paramKey = sb.toString();
        long timeStamp = System.currentTimeMillis();
        MaterialParamBO materialParamBO = MaterialParamBO.builder().tag(tag).timeStamp(timeStamp).x1(rightBottomX)
                .x2(leftTopX).y1(indexRightBottomY).y2(indexLeftTopY).pointType(type).build();
        String s = JSONObject.toJSONString(materialParamBO);
        redisService.setSerializable(paramKey,s);
        StringBuilder resSb = new StringBuilder(GlobalConstant.MATERIAL_AREA_RESULT_REDIS_PREFIX);
        resSb.append(tag);
        String resKey = resSb.toString();
        while (true){
            try {
                if (count > 5){
                    log.error("没有获取到抓点信息");
                    return null;
                }
                Thread.sleep(800);
//                timeStamp = System.currentTimeMillis();
//                materialParamBO = MaterialParamBO.builder().tag(tag).timeStamp(timeStamp).x1(rightBottomX)
//                        .x2(leftTopX).y1(indexRightBottomY).y2(indexLeftTopY).pointType(type).build();
//                s = JSONObject.toJSONString(materialParamBO);
                JSONObject resObj = (JSONObject) redisService.get(resKey);
                MaterialResultBO materialResultBO = JSONObject.parseObject(resObj.toString(),MaterialResultBO.class);
                if(materialResultBO != null){
                    Long resTimeStamp = materialParamBO.getTimeStamp();
                    if(resTimeStamp != timeStamp){
                        log.error("返回时间戳不一致。库区扫描异常！！！！,异常信息为：{}",materialResultBO);
                        throw new AddTaskException("库区扫描异常");
                    }


                    log.info("返回的抓点数据为：{}",materialResultBO);
                    if(materialResultBO.getRetStatus() == 0 && CollectionUtil.isNotEmpty(materialResultBO.getRetSets())){
                        //返回了数据点
                        List<MaterialAreaPointBO> retSets = materialResultBO.getRetSets();
                        if(type == 0){
                            //返回抓点
                            log.info("返回抓点,返回了的数据为：{},长度为：{}",retSets,retSets.size());
                            return retSets.get(0).toCoord();
                        } else {
                            //返回放点
                            return retSets.get(retSets.size() - 1).toCoord();
                        }

                    }
                }
            } catch (Exception e){
                log.info("获取料场扫描点异常",e);
            }

            log.info("循环获取抓点中。。。。。");
            redisService.setSerializable(paramKey,s);
            count++;
            log.info("重新获取抓点。。。。。");

        }

    }



    public static boolean getTankCarScanActFinish(TankCarNoEnum tankCarNoEnum){

        if(TankCarNoEnum.NO_1 == tankCarNoEnum){
            return AddTaskConstant.TANK_CAR_NO1_FINISH_FLAG;
        }

        if(TankCarNoEnum.NO_2 == tankCarNoEnum){
            return AddTaskConstant.TANK_CAR_NO2_FINISH_FLAG;
        }
        return AddTaskConstant.TANK_CAR_NO3_FINISH_FLAG;

    }



    public static void setTankCarScanActFinish(TankCarNoEnum tankCarNoEnum,boolean value){

        if(TankCarNoEnum.NO_1 == tankCarNoEnum){
            AddTaskConstant.TANK_CAR_NO1_FINISH_FLAG = value;
        }

        if(TankCarNoEnum.NO_2 == tankCarNoEnum){
            AddTaskConstant.TANK_CAR_NO2_FINISH_FLAG = value;
        }

        if(TankCarNoEnum.NO_3 == tankCarNoEnum){
            AddTaskConstant.TANK_CAR_NO3_FINISH_FLAG = value;
        }

    }


    private static List<DropPosition> filterTankCarPoint(String spanNo,TankCarPointBO tankCarPointBO) throws AddTaskException {
        List<DropPosition> resList = new ArrayList<>();
        if (AddTaskConstant.WASTE_STEEL_SPAN_NO.equals(spanNo)) {
            //废钢跨
            TreeSet<DropPosition> dropPos = tankCarPointBO.getDropPos();

            for (DropPosition dropPo : dropPos) {

                if (dropPo.getY() < 380 && dropPo.getY() > 250) {
                    resList.add(dropPo);
                }
            }
        } else {
            //渣钢跨
            TreeSet<DropPosition> dropPos = tankCarPointBO.getDropPos();

            for (DropPosition dropPo : dropPos) {
                if (dropPo.getY() < 190 && dropPo.getY() > 20) {
                    resList.add(dropPo);
                }
            }
        }

        if(CollectionUtil.isEmpty(resList)){
            throw new AddTaskException("过滤槽车扫描点后，没有合格的点");
        }
        return resList;
    }
}
